﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Furiant.Figment.Agents;
using Furiant.Figment.Agents.Inventory;

namespace Furiant.Figment.Items.Lootable
{
    public class EquipSlotMapCollection : IEnumerable<EquipSlotMap>
    {
        private readonly List<EquipSlotMap> _collection = new List<EquipSlotMap>();



        #region Properties

        public EquipSlotMap this[int index] { get { return _collection[index]; } }

        public EquipSlotMap this[EquipSlotDefinition primary] { get { return _collection.Single(p => p.Primary == primary); } }

        public IEnumerable<EquipSlotDefinition> PrimarySlots { get { return _collection.Select(p => p.Primary); } }

        public IEnumerable<EquipSlotDefinition> ReferredSlots
        {
            get
            {
                var slots = new List<EquipSlotDefinition>();

                foreach (var referredCollection in _collection.Select(p => p.Referred))
                {
                    slots.AddRange(referredCollection.Where(p => !slots.Contains(p)));
                }

                return slots;
            }
        }

        public IEnumerable<EquipSlotDefinition> Slots
        {
            get
            {
                var slots = new List<EquipSlotDefinition>();
                
                foreach(var map in _collection)
                {
                    slots.AddRange(map);
                }

                return slots.Distinct();
            }
        }

        #endregion

        #region Methods

        public bool Contains(EquipSlotDefinition slot)
        {
            return Slots.Contains(slot);
        }

        public bool ContainsPrimary(EquipSlotDefinition primary)
        {
            return PrimarySlots.Contains(primary);
        }

        public bool ContainsReferred(EquipSlotDefinition referred)
        {
            return ReferredSlots.Contains(referred);
        }

        public void Add(EquipSlotMap item)
        {
            if (PrimarySlots.Contains(item.Primary))
            {
                throw new ArgumentException("Collection cannot contain multiple items with the same value at index 0.");
            }
        }

        public bool Remove(EquipSlotMap item)
        {
            return _collection.Remove(item);
        }

        public bool Remove(EquipSlotDefinition primary)
        {
            var found = this[primary];

            return _collection.Remove(found);
        }


        public IEnumerator<EquipSlotMap> GetEnumerator()
        {
            return _collection.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}
